#ifndef LOGHELPER_H
#define LOGHELPER_H

#include "Mutex.h"
#include <sys/stat.h>
#include <stdarg.h>
#include <string.h>

#define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1):__FILE__)

#define LOG2(lev, mesg, ...)  _WriteLog(__FILENAME__, __LINE__, lev, mesg, ##__VA_ARGS__)

void _WriteLog(const char* filename, int line, int level, const char* mesg, ...);

#define MAX_PATH 256

#define	ASSERT(expression)              {   \
        if (!(expression))              {   \
        char __log__[100] = {0}; \
        snprintf(__log__, sizeof(__log__), "Assertion(%s) failed: func %s", #expression, __func__); \
            LOG(__log__, ERROR); \
        }                   \
    }

enum Log_Level
{
    TRACE,
    DEBUG,
    INFO,
    WARM,
    ERROR,
    FATAL,
    NUM_LOG_LEVELS
};

struct Log_Message
{
    time_t          occur_time;       //time
    int             pid;
    Log_Level       level;
    const char*     filename;         //file name
    int             occur_no;         //line number
    const char*     error_content;    //content
};

typedef struct Log_Message Log_Message_T;

class CLogHelper
{
private:
    CLogHelper(const char* FullDirPath);
    static CLogHelper *m_pInstance;
    static CMutexLock m_Mutex;
    class CGarbo
    {
    public:
        ~CGarbo()
        {
            if(CLogHelper::m_pInstance)
                delete CLogHelper::m_pInstance;
        }
    };
    static CGarbo Garbo;

    FILE *m_fp;
    char m_DirPath[MAX_PATH];
    char m_FullPathFileName[MAX_PATH];
    
    long int GetFileSize()
    {
        fseek(m_fp, SEEK_SET, SEEK_END ); //size must <= 2G
        return ftell(m_fp);
    }

    //size can be > 2G
    unsigned long long GetFileSize(const char *filename)
    {
        struct stat buf;
        if(stat(filename, &buf)<0)
        {
            return 0;
        }
        return (unsigned long long)buf.st_size;
    }

    bool IsFileAlready();
    void AssertFileAlready()
    {
        assert(IsFileAlready());
    }

public:
    ~CLogHelper();
    static CLogHelper* GetInstance(const char* FullDirPath = NULL);
    void Log(Log_Message_T *emt);
    void Log(const char* msg);

    void Delete_File(char* cleandir, int days);

    void Delete_FileCount(int count);
};
#endif // LOGHELPER_H
